/*---------------------------------------------------------------------
//纯音频的数据采集：气导+骨导
//保存路径:/data/ai
modified by mtd at 2024.11.25
-----------------------------------------------------------------------*/
#include "client_t.h"
#include <signal.h>
#include "taiic_key.h"
#include "taiic_sensor.h"
#include <thread>
#include <cstdio> //包含rename函数
#include <dirent.h>

#include "isp/taiic_isp_model.h"
#include "taiic_uart/taiic_uart_sum.h"
#include <mutex>
#include <condition_variable>

using namespace std;

// #define SESSION 10000
// #define TYPE 44


// 判断当前图像是否正在采集
RK_BOOL is_model_run = RK_FALSE;

TAIIC_MODE_STATE_CTX_S *mode_state; // 模式状态相关参数

long air_pcm_size = 0;
long bone_pcm_size = 0;

char aiCmd[256] = "/data/ai/";


FILE *tmpAiFp_air=NULL;
FILE *tmpAiFp_bone=NULL;

int ai_save = 0;
int vi_save = 0;

char buffer[1024];
int nCount=0;

//function declaration
static void ai_vi_save_end(int ai, int vi);
void *ai_uart_func(void *args); // 副板->主板气导音频数据采集
static void app_key_callback(TAIIC_KEY_STATE old_state, TAIIC_KEY_NAME key_name, TAIIC_KEY_STATE key_state);

char *serverAddr = "192.168.54.95";// 默认的服务端ip 127.0.0.1 本地回环

int ai_sock_cli;
#define BUF_SIZE 1024
/*---------------------------------------------------------------------
                            全局变量/宏定义/结构体/函数声明
-----------------------------------------------------------------------*/
static void sigterm_handler(int sig);
int cnt = 0;

/*----------------------------------------------------------------
                            主函数main
-----------------------------------------------------------------*/
int main(int argc, char **argv)
{
    // UART串口初始化
    serial_init();
    
    //soc connect
    if (argc > 1)
    {
        serverAddr = argv[1]; // 服务器的ip地址
    }
   
    printf("set server add is %s\n", serverAddr);

    // 初始化socket、连接服务器
    ai_sock_cli = init_socket(serverAddr);

    DIR *myaidir = NULL;
    if ((myaidir = opendir(aiCmd)) == NULL) // 创建文件夹ai
    {
        bool ret1 = mkdir(aiCmd, 0755);
        RK_LOGI("%s created sucess!/n", aiCmd);
    }
    
    //aivi data callback
    aivi_save_end_callback(ai_vi_save_end); 
    // initial mode state
    mode_state = reinterpret_cast<TAIIC_MODE_STATE_CTX_S *>(malloc(sizeof(TAIIC_MODE_STATE_CTX_S)));
    memset(mode_state, 0, sizeof(TAIIC_MODE_STATE_CTX_S));

    //按键检测
    taiic_all_key_registers(mode_state, app_key_callback);

    //ai
    pthread_t tid_ai_uart;
    pthread_create(&tid_ai_uart, NULL, ai_uart_func, NULL);
    pthread_join(tid_ai_uart, NULL);

    //setup the SIGINT to ctrl+c and handing de-init process
    signal(SIGINT, sigterm_handler);
    RK_MPI_SYS_Init();
    /////////////////////////isp release end////////////////////////////
    RK_MPI_SYS_Exit();
    uint_socket(ai_sock_cli); // 关闭socket客户端

    return 0;
}
/*---------------------------------------------------------------
                          函数实现
-----------------------------------------------------------------*/
static void sigterm_handler(int sig)
{
    RK_LOGI("Catched SIGINT %d\n", sig);
}

void *ai_uart_func(void *args) // 副板->主板气导音频数据采集
{
    while (true)
    {
        std::unique_lock<std::mutex> lock(mtx_ai);
        //等待ai_start变为true
        cv_ai.wait(lock, []()
                   { return ai_start; });
        
        // 清除工作可用的标志，为下一次循环做准备
        ai_start = false;
        //开始执行任务,气导音频(.pcm)文件存在则删除
        if(fileExists(air_pcm_path))
        {
            if (remove(air_pcm_path) == 0)
            {
                printf("air pcm file exists, and delete successfully\n");
            }
            else
            {
                printf("air pcm file delete failed\n");
            }
        }
        //开始执行任务,骨导音频(.pcm)文件存在则删除
        if(fileExists(bone_pcm_path))
        {
            if (remove(bone_pcm_path) == 0)
            {
                printf("bone pcm file exists, and delete successfully\n");
            }
            else
            {
                printf("bone pcm file delete failed\n");
            }
        }

        //开始执行任务
        mtx_uart.lock();
        uart_main_func(5, 3, 0, 0);//骨+气导数据
        mtx_uart.unlock();

        while (1)
        {
            air_pcm_size = getFileSize(air_pcm_path);
            bone_pcm_size = getFileSize(bone_pcm_path);
            // printf("%ld\n", pcm_size);
            if((air_pcm_size == PCM_SIZE_SOC)&&(bone_pcm_size == PCM_SIZE_SOC)) //53280=111*480
            {
                ai_save = 1; // ai save end
                //尝试重命名文件air
                if (rename(air_pcm_path, aiCmdFinal_air) == 0)
                {
                    printf("air rename success!\n");
                }else{
                    perror("air rename fail!\n");// 如果rename失败，输出错误信息
                }

                //尝试重命名文件bone
                if(rename(bone_pcm_path, aiCmdFinal_bone) == 0)
                {
                    printf("bone rename success!\n");
                }else{ 
                    perror("bone rename fail!\n");// 如果rename失败，输出错误信息
                }

                RK_LOGD("=====save ai finish==\n");
                break;
            }
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); //0.1s

        if(ai_save == 1)
        {
            ai_vi_save_end(vi_save, ai_save); //send to pc
        }
    }
    pthread_exit(NULL);
}

static void ai_vi_save_end(int ai, int vi)
{
    printf("===soc start==\n");

    tmpAiFp_air = fopen(aiCmdFinal_air, "rb"); //以二进制方式打开（创建）文件
    while((nCount = fread(buffer, 1, 1024, tmpAiFp_air)) > 0)
    {
        send(ai_sock_cli, buffer, nCount, 0);
        // printf("===send ai_air len is %d==\n", nCount);
    }
    //send bone 
    tmpAiFp_bone = fopen(aiCmdFinal_bone, "rb"); // 以二进制方式打开（创建）文件
    while((nCount = fread(buffer, 1, 1024, tmpAiFp_bone)) > 0)
    {
        send(ai_sock_cli, buffer, nCount, 0);
        //printf("===send ai_bone len is %d==\n", nCount);
    }

    printf("===soc end==\n");

    mtx_uart.lock();
    uart_main_func(1,2,0,0);
    mtx_uart.unlock();
    
    system("rm -rf /data/ai/*");
    ai_save = 0;

    is_model_run = RK_FALSE;

    printf("====please speak next session===\n");//RK_LOGW("====please speak next session===\n");
}

static void app_key_callback(TAIIC_KEY_STATE old_state, TAIIC_KEY_NAME key_name, TAIIC_KEY_STATE key_state)
{
    // 判断key_name去实现对应功能,key_name=0表示音频线模式
    RK_LOGE("old_state==%d, key_name==%d, key_state==%d,count=%d\n", old_state, key_name, key_state, cnt++);

    switch (key_name)
    {
    case TAIIC_PTT:
        mode_state->ptt_flag = key_state;
        if (mode_state->mode1_flag == MODE_DOWN) // PTT按键按下
        {
            if ((!is_model_run)) //唇图模式
            {
                is_model_run = RK_TRUE;
                snprintf(aiCmdFinal_air, sizeof(aiCmdFinal_air), "%ssession_air%d_%d.pcm", aiCmd, sessionNum, typeNUm);
                RK_LOGI("=====air ai cmd is %s===\n", aiCmdFinal_air);

                snprintf(aiCmdFinal_bone, sizeof(aiCmdFinal_bone), "%ssession_bone%d_%d.pcm", aiCmd, sessionNum, typeNUm);
                RK_LOGI("=====bone ai cmd is %s===\n", aiCmdFinal_bone);

                /*mtx_uart.lock();
                uart_main_func(1, 1, 0, 0);
                mtx_uart.unlock();*/
                //音频采集开始
                {
                    std::lock_guard<std::mutex> lock(mtx_ai);
                    ai_start = true; // 设置标志位为true，允许ai开始执行
                }
                cv_ai.notify_one();

                typeNUm++;
                if (typeNUm == TYPE)
                {
                    sessionNum++;
                    typeNUm = 0;
                }
                if (sessionNum == SESSION)
                {
                    sessionNum = 0;
                    exit(0);
                }

            }
        }

        break;
    }
}




